package com.hyacinth.common.jpql;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.hyacinth.common.constant.ThreadLocals;

public class SimpleJPQL {
	
	private String alias = "o";
	private Class<?> entityClass;
	private Limit limit;
	private OperateType operateType;
	private Field field;
	private Where where;
	private Order order;

	private EntityManager manager() {
		return ThreadLocals.ENTITY_MANAGER.get();
	}
	
	public SimpleJPQL(Class<?> entityClass) {
		this.entityClass = entityClass;
		this.setOperateType(OperateType.SELECT);
		this.field = new Field(this.alias);
	}
	
	public SimpleJPQL setOperateType(OperateType operateType) {
		this.operateType = operateType;
		return this;
	}
	
	@SuppressWarnings("unchecked")
	public <T> List<T> multi(Class<T> resultType) {
		Query query = manager().createQuery(this.toString());
		assign(query);
		return query.getResultList();
	}
	
	public Object single() {
		Query query = manager().createQuery(this.toString());
		assign(query);
		return query.getSingleResult();
	}
	
	public Limit limit() {
		if(limit == null) {
			limit = new Limit();
		}
		return this.limit;
	}
	
	public Where where() {
		if(where == null) {
			where = new Where(this.alias);
		}
		return this.where;
	}
	
	public Order order() {
		if(order == null) {
			order = new Order(this.alias);
		}
		return this.order;
	}
	
	public Field field() {
		if(field == null) {
			field = new Field(this.alias);
		}
		return this.field;
	}
	
	public String toString() {
		StringBuilder statement = new StringBuilder();
		switch(operateType) {
			case SELECT : 
				statement.append("SELECT ").append(this.field).append(" FROM ").
							append(this.entityClass.getSimpleName())
								.append(" ").append(this.alias);
			break;
			case UPDATE :
			break;
			case INSERT :
			break;
			case DELETE :
			break;
			default:
			break;
		}
		if(where!=null)
			statement.append(" WHERE ").append(this.where.toString());
		if(order!=null)
			statement.append(" ORDER BY ").append(this.order.toString());
		//System.out.println(new Date() +"---"+ statement.toString());
		return statement.toString();
	}
	
	private void assign(Query query) {
		if(where != null)
			where.assign(query);
		if(limit != null)
			limit.assign(query);
	}

}
